from trinity.sceneRenderJobBase import SceneRenderJobBase
import interiorVisualizations as iVis
import trinity
import blue

def CreateEveSceneRenderJobInterior(name = None, stageKey = None):
    newRJ = EveSceneRenderJobInterior()
    if (name is not None):
        newRJ.ManualInit(name)
    else:
        newRJ.ManualInit()
    newRJ.SetMultiViewStage(stageKey)
    return newRJ



class EveSceneRenderJobInterior(SceneRenderJobBase):
    renderStepOrder = ['UPDATE_SCENE',
     'UPDATE_BACKGROUND_SCENE',
     'UPDATE_STEREO',
     'UPDATE_BACKGROUND_CAMERA',
     'UPDATE_UI',
     'SET_VIEWPORT',
     'SET_DEPTH',
     'SET_BACKGROUND_RT',
     'SET_BACKGROUND_PROJECTION',
     'SET_BACKGROUND_VIEW',
     'CLEAR_BACKGROUND_RT',
     'RENDER_BACKGROUND_SCENE',
     'CLEAR_BACKGROUND_DEPTH',
     'SET_PROJECTION',
     'SET_VIEW',
     'VISIBILITY_QUERY',
     'SET_VISIBILITY_RESULT',
     'SET_VISUALIZATION',
     'SET_DEPTH',
     'SET_PREPASS_RT',
     'CLEAR_PREPASS',
     'BEGIN_MANAGED_RENDERING',
     'RENDER_PREPASS',
     'SET_LIGHT_RT',
     'CLEAR_LIGHTS',
     'SET_VAR_LIGHTS_DEPTH',
     'SET_VAR_LIGHTS_PREPASS',
     'RENDER_LIGHTS',
     'RENDER_SSAO',
     'SET_GATHER_RT',
     'CLEAR_GATHER_RT',
     'SET_VAR_LIGHTS',
     'RENDER_GATHER',
     'SET_VAR_POST_PROCESS_GATHER',
     'SET_ILR_THRESHOLD_RT',
     'SET_VAR_ILR_KERNEL_THRESHOLD',
     'RENDER_ILR_THRESHOLD',
     'SET_VAR_ILR_THRESHOLD_0',
     'SET_VAR_ILR_KERNEL_0',
     'SET_ILR_BLOOM_RT_0',
     'RENDER_ILR_BLOOM_0',
     'SET_VAR_ILR_THRESHOLD_1',
     'SET_VAR_ILR_KERNEL_1',
     'SET_ILR_BLOOM_RT_1',
     'RENDER_ILR_BLOOM_1',
     'SET_VAR_ILR_MERGE_BLOOM0',
     'SET_VAR_ILR_MERGE_BLOOM1',
     'SET_VAR_ILR_MERGE_BLOOM2',
     'SET_ILR_MERGE_RT',
     'RENDER_ILR_MERGE',
     'SET_POST_PROCESS_COMPOSITE_RT',
     'SET_VAR_ILR_BLOOM',
     'SET_VAR_ILR_REFLECTIONS_0',
     'SET_VAR_ILR_REFLECTIONS_1',
     'POST_PROCESS',
     'RENDER_FLARES',
     'END_MANAGED_RENDERING',
     'UPDATE_TOOLS',
     'RENDER_INFO',
     'RENDER_VISUAL',
     'RENDER_TOOLS',
     'RESTORE_DEPTH',
     'RENDER_UI']
    multiViewStages = [('SETUP',
      True,
      ['UPDATE_SCENE',
       'UPDATE_BACKGROUND_SCENE',
       'SET_DEPTH',
       'BEGIN_MANAGED_RENDERING']),
     ('SETUP_VIEW',
      False,
      ['SET_VIEWPORT',
       'SET_PROJECTION',
       'SET_VIEW',
       'VISIBILITY_QUERY',
       'FILTER_VISIBILITY_RESULT']),
     ('SETUP_BACKGROUND_RENDERING',
      True,
      ['SET_GATHER_RT', 'CLEAR_BACKGROUND_RT']),
     ('RENDER_BACKGROUNDS',
      False,
      ['SET_VIEWPORT',
       'UPDATE_BACKGROUND_CAMERA',
       'SET_BACKGROUND_PROJECTION',
       'SET_BACKGROUND_VIEW',
       'RENDER_BACKGROUND_SCENE']),
     ('RESTORE_FROM_BACKGROUND_RENDERING',
      True,
      ['CLEAR_BACKGROUND_DEPTH']),
     ('SETUP_PREPASS_PASS',
      True,
      ['SET_PREPASS_RT', 'CLEAR_PREPASS']),
     ('PREPASS',
      False,
      ['SET_VIEWPORT',
       'SET_VIEW',
       'SET_PROJECTION',
       'SET_VISIBILITY_RESULT',
       'SET_VISUALIZATION',
       'ENABLE_WIREFRAME',
       'RENDER_PREPASS',
       'RESTORE_WIREFRAME']),
     ('SETUP_LIGHT_PASS',
      True,
      ['SET_LIGHT_RT',
       'CLEAR_LIGHTS',
       'SET_VAR_LIGHTS_DEPTH',
       'SET_VAR_LIGHTS_PREPASS']),
     ('LIGHT_PASS',
      False,
      ['SET_VIEWPORT',
       'SET_VIEW',
       'SET_PROJECTION',
       'SET_VISIBILITY_RESULT',
       'SET_VISUALIZATION',
       'RENDER_LIGHTS']),
     ('SETUP_GATHER',
      True,
      ['RENDER_SSAO',
       'SET_GATHER_RT',
       'SET_VAR_LIGHTS']),
     ('GATHER_PASS',
      False,
      ['SET_VIEWPORT',
       'SET_VIEW',
       'SET_PROJECTION',
       'SET_VISIBILITY_RESULT',
       'SET_VISUALIZATION',
       'ENABLE_WIREFRAME',
       'DISABLE_CUBEMAP',
       'RENDER_GATHER',
       'ENABLE_CUBEMAP',
       'RESTORE_WIREFRAME',
       'RENDER_FLARES']),
     ('END_MANAGED_RENDERING',
      True,
      ['END_MANAGED_RENDERING']),
     ('TOOLS',
      False,
      ['SET_VIEWPORT',
       'SET_VIEW',
       'SET_PROJECTION',
       'UPDATE_TOOLS',
       'RENDER_INFO',
       'RENDER_PROXY',
       'RENDER_VISUAL',
       'RENDER_TOOLS',
       'RENDER_KYNAPSE']),
     ('TEARDOWN',
      True,
      ['RESTORE_DEPTH'])]
    visualizations = [iVis.DisableVisualization,
     ('Geometry', [iVis.WhiteVisualization,
       iVis.ObjectNormalVisualization,
       iVis.ShadedObjectNormalVisualization,
       iVis.TangentVisualization,
       iVis.BiTangentVisualization,
       iVis.TexCoord0Visualization,
       iVis.TexCoord1Visualization,
       iVis.TexelDensityVisualization,
       iVis.OverdrawVisualization,
       iVis.DepthVisualization]),
     ('Textures', [('Normal Map', [iVis.NormalMapVisualization,
         iVis.NormalMapWorldVisualization,
         iVis.NormalMapUnpackedVisualization,
         iVis.NormalMapRedInvertedVisualization,
         iVis.NormalMapGreenInvertedVisualization,
         iVis.NormalMapBothInvertedVisualization]),
       ('Shaded Normal Map', [iVis.ShadedNormalMapVisualization,
         iVis.ShadedNormalMapUnpackedVisualization,
         iVis.ShadedNormalMapRedInvertedVisualization,
         iVis.ShadedNormalMapGreenInvertedVisualization,
         iVis.ShadedNormalMapBothInvertedVisualization]),
       iVis.GlowMapVisualization,
       iVis.GlowMapUnpackedVisualization,
       iVis.SpecularMapVisualization,
       iVis.SpecularMapUnpackedVisualization,
       iVis.DiffuseMapVisualization,
       iVis.ReflectionMapVisualization,
       iVis.AOMapVisualization]),
     ('Lighting', [('Enlighten', [iVis.EnlightenDetailChartsVisualization,
         iVis.EnlightenTargetChartsVisualization,
         iVis.EnlightenOnlyVisualization,
         iVis.EnlightenTargetDetailVisualization,
         iVis.EnlightenOutputDensityVisualization,
         iVis.EnlightenAlbedoVisualization,
         iVis.EnlightenObjectTexcoordVisualization,
         iVis.EnlightenNaughtyPixelsVisualization]),
       ('All Light Volumes', [iVis.LightVolumeWhiteVisualization,
         iVis.LightVolumeNormalVisualization,
         iVis.LightVolumeShadowResolutionVisualization,
         iVis.LightVolumeShadowRelativeResolutionVisualization]),
       ('Primary Light Volumes', [iVis.PrimaryLightVolumeWhiteVisualization,
         iVis.PrimaryLightVolumeNormalVisualization,
         iVis.PrimaryLightVolumeShadowResolutionVisualization,
         iVis.PrimaryLightVolumeShadowRelativeResolutionVisualization]),
       ('Secondary Light Volumes', [iVis.SecondaryLightVolumeWhiteVisualization,
         iVis.SecondaryLightVolumeNormalVisualization,
         iVis.SecondaryLightVolumeShadowResolutionVisualization,
         iVis.SecondaryLightVolumeShadowRelativeResolutionVisualization]),
       ('Shadowcasting Light Volumes', [iVis.ShadowcastingLightVolumeWhiteVisualization,
         iVis.ShadowcastingLightVolumeNormalVisualization,
         iVis.ShadowcastingLightVolumeShadowResolutionVisualization,
         iVis.ShadowcastingLightVolumeShadowRelativeResolutionVisualization]),
       ('Transparent Light Volumes', [iVis.TransparentLightVolumeWhiteVisualization,
         iVis.TransparentLightVolumeNormalVisualization,
         iVis.TransparentLightVolumeShadowResolutionVisualization,
         iVis.TransparentLightVolumeShadowRelativeResolutionVisualization]),
       iVis.PrePassLightingOnlyVisualization,
       iVis.PrePassLightNormalVisualization,
       iVis.PrePassLightDepthVisualization,
       iVis.PrePassLightWorldPositionVisualization,
       iVis.PrePassLightOverdrawVisualization,
       iVis.ShadowOnlyVisualization])]

    def _ManualInit(self, name = 'EveSceneRenderJobInterior'):
        self.depthFormat = None
        self.prePassFormat = None
        self.lightAccumulationFormat = None
        self.backBufferDepthStencil = None
        self.backBufferRenderTarget = None
        self.prePassDepthStencil = None
        self.prePassRenderTarget = None
        self.lightAccumulationTarget = None
        self.gatherTarget = None
        self.ilrMergeTarget = None
        self.ilrBloomTarget0 = None
        self.ilrBloomTarget1 = None
        self.ilrBloomTarget2 = None
        self.ilrBloomFormat = None
        self.renderTargetList = None
        self.ui = None
        self.backgroundScene = None
        self.backgroundUpdateFunction = None
        self.ilrThresholdShader = None
        self.ilrBloomShader = None
        self.ilrMergeShader = None
        self.ilrEnabled = False
        self.lutEnabled = False
        self.postProcessShader = trinity.Tr2ShaderMaterial()
        self.postProcessShader.highLevelShaderName = 'PostProcess'



    def _SetScene(self, scene):
        self.SetStepAttr('UPDATE_SCENE', 'object', scene)
        self.SetStepAttr('VISIBILITY_QUERY', 'queryable', scene)
        self.SetStepAttr('SET_VISIBILITY_RESULT', 'queryable', scene)
        self.SetStepAttr('BEGIN_MANAGED_RENDERING', 'scene', scene)
        self.SetStepAttr('RENDER_PREPASS', 'scene', scene)
        self.SetStepAttr('RENDER_LIGHTS', 'scene', scene)
        self.SetStepAttr('RENDER_GATHER', 'scene', scene)
        self.SetStepAttr('RENDER_FLARES', 'scene', scene)
        self.SetStepAttr('END_MANAGED_RENDERING', 'scene', scene)



    def _CreateBasicRenderSteps(self):
        self.AddStep('UPDATE_SCENE', trinity.TriStepUpdate(self.GetScene()))
        result = trinity.Tr2VisibilityResults()
        self.AddStep('VISIBILITY_QUERY', trinity.TriStepVisibilityQuery(self.GetScene(), result))
        self.AddStep('SET_VISIBILITY_RESULT', trinity.TriStepSetVisibilityResults(self.GetScene(), result))
        self.AddStep('SET_PREPASS_RT', trinity.TriStepSetRenderTarget())
        self.AddStep('CLEAR_PREPASS', trinity.TriStepClear((0, 0, 0, 0), 1.0, 0))
        self.AddStep('BEGIN_MANAGED_RENDERING', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_BEGIN_RENDER))
        self.AddStep('RENDER_PREPASS', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_PRE_PASS))
        self.AddStep('SET_LIGHT_RT', trinity.TriStepSetRenderTarget())
        self.AddStep('CLEAR_LIGHTS', trinity.TriStepClear((0, 0, 0, 0), None, None))
        self.AddStep('RENDER_LIGHTS', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_LIGHT_PASS))
        try:
            ssao = trinity.Load('res://Graphics/Interior/SSAO.red')
            blue.resMan.Wait()
            ssao.useNormalTexture = True
            self.AddStep('RENDER_SSAO', ssao)
        except:
            pass
        self.AddStep('SET_GATHER_RT', trinity.TriStepSetRenderTarget())
        self.AddStep('CLEAR_GATHER_RT', trinity.TriStepClear((0, 0, 0, 0), None, None))
        self.AddStep('RENDER_GATHER', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_GATHER_PASS))
        self.AddStep('RENDER_FLARES', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_FLARE_PASS))
        self.AddStep('END_MANAGED_RENDERING', trinity.TriStepRenderPrePass(self.GetScene(), trinity.TRIPREPASS_END_RENDER))



    def AddBloomStep(self, source, target, step, kernelWidth):
        self.AddStep(('SET_VAR_ILR_THRESHOLD_%d' % step), trinity.TriStepSetVariableStore('BloomMap', source))
        self.AddStep(('SET_VAR_ILR_KERNEL_%d' % step), trinity.TriStepSetVariableStore('BloomWidth', ((kernelWidth / source.width), (kernelWidth / source.height))))
        self.AddStep(('SET_ILR_BLOOM_RT_%d' % step), trinity.TriStepSetRenderTarget(target.GetSurfaceLevel(0)))
        self.AddStep(('RENDER_ILR_BLOOM_%d' % step), trinity.TriStepRenderFullScreenShader(self.ilrBloomShader))



    def ChooseBufferFormats(self):
        shaderModel = trinity.GetShaderModel()
        self.depthFormat = trinity.TRIFMT_D24S8
        customDepthFormat = False
        if (shaderModel == 'SM_3_0_HI'):
            self.prePassFormat = trinity.TRIFMT_A16B16G16R16
            self.lightAccumulationFormat = trinity.TRIFMT_A16B16G16R16F
            self.ilrBloomFormat = trinity.TRIFMT_A16B16G16R16F
            self.gatherFormat = trinity.TRIFMT_A16B16G16R16F
        elif (shaderModel == 'SM_3_0_DEPTH'):
            self.depthFormat = trinity.TRIFMT_INTZ
            self.prePassFormat = trinity.TRIFMT_A16B16G16R16
            self.lightAccumulationFormat = trinity.TRIFMT_A16B16G16R16F
            self.ilrBloomFormat = trinity.TRIFMT_A16B16G16R16F
            self.gatherFormat = trinity.TRIFMT_A16B16G16R16F
            customDepthFormat = True
        else:
            self.prePassFormat = trinity.TRIFMT_A8R8G8B8
            self.lightAccumulationFormat = trinity.TRIFMT_A8R8G8B8
        if not customDepthFormat:
            self.RemoveStep('SET_DEPTH')
            self.RemoveStep('RESTORE_DEPTH')



    def DoReleaseResources(self, level):
        self.SetRenderTargets(None, None, None, None, None, None, None, None, None, None)
        self.renderTargetList = None
        self.backBufferDepthStencil = None
        self.gatherTarget = None
        self.backBufferRenderTarget = None
        self.prePassDepthStencil = None
        self.prePassRenderTarget = None
        self.lightAccumulationTarget = None
        self.ilrMergeTarget = None
        self.ilrBloomTarget0 = None
        self.ilrBloomTarget1 = None
        self.ilrBloomTarget2 = None



    def InitializeShaders(self):
        self.ilrBloomShader = trinity.Tr2ShaderMaterial()
        self.ilrBloomShader.highLevelShaderName = 'ILR_Bloom'
        self.ilrBloomShader.BindLowLevelShader(['none'])
        self.ilrThresholdShader = trinity.Tr2ShaderMaterial()
        self.ilrThresholdShader.highLevelShaderName = 'ILR_Threshold'
        self.ilrThresholdShader.BindLowLevelShader(['none'])
        self.ilrMergeShader = trinity.Tr2ShaderMaterial()
        self.ilrMergeShader.highLevelShaderName = 'ILR_Merge'
        self.ilrMergeShader.BindLowLevelShader(['none'])



    def DoPrepareResources(self):
        if ((not self.enabled) or (not self.canCreateRenderTargets)):
            return 
        if (self.renderTargetList is None):
            device = trinity.device
            self.ChooseBufferFormats()
            if (self.backBufferDepthStencil is None):
                self.backBufferDepthStencil = device.GetDepthStencilSurface()
            if (self.backBufferRenderTarget is None):
                self.backBufferRenderTarget = device.GetRenderTarget()
            width = device.GetPresentParameters()['BackBufferWidth']
            height = device.GetPresentParameters()['BackBufferHeight']
            if ((self.depthFormat is not None) and (self.prePassDepthStencil is None)):
                if (self.depthFormat == self.backBufferDepthStencil.format):
                    self.prePassDepthStencil = self.backBufferDepthStencil
                else:
                    self.prePassDepthStencil = device.CreateTexture(width, height, 1, trinity.TRIUSAGE_DEPTHSTENCIL, self.depthFormat, trinity.TRIPOOL_DEFAULT)
            if ((self.prePassFormat is not None) and (self.prePassRenderTarget is None)):
                self.prePassRenderTarget = device.CreateTexture(width, height, 1, trinity.TRIUSAGE_RENDERTARGET, self.prePassFormat, trinity.TRIPOOL_DEFAULT)
            if ((self.lightAccumulationFormat is not None) and (self.lightAccumulationTarget is None)):
                self.lightAccumulationTarget = device.CreateTexture(width, height, 1, trinity.TRIUSAGE_RENDERTARGET, self.lightAccumulationFormat, trinity.TRIPOOL_DEFAULT)
            self._RebuildPostProcess()
            self.renderTargetList = (blue.BluePythonWeakRef(self.backBufferDepthStencil),
             blue.BluePythonWeakRef(self.backBufferRenderTarget),
             blue.BluePythonWeakRef(self.prePassDepthStencil),
             blue.BluePythonWeakRef(self.prePassRenderTarget),
             blue.BluePythonWeakRef(self.lightAccumulationTarget),
             blue.BluePythonWeakRef(self.ilrBloomTarget0),
             blue.BluePythonWeakRef(self.ilrBloomTarget1),
             blue.BluePythonWeakRef(self.ilrBloomTarget2),
             blue.BluePythonWeakRef(self.ilrMergeTarget),
             blue.BluePythonWeakRef(self.gatherTarget))
        thingToSet = (x.object for x in self.renderTargetList)
        self.SetRenderTargets(*thingToSet)



    def SetUI(self, ui):
        if (ui is None):
            self.RemoveStep('UPDATE_UI')
            self.RemoveStep('RENDER_UI')
        else:
            self.AddStep('UPDATE_UI', trinity.TriStepUpdate(ui))
            self.AddStep('RENDER_UI', trinity.TriStepRenderUI(ui))



    def SetCameraView(self, view):
        SceneRenderJobBase.SetCameraView(self, view)
        self.UpdateBackgroundCameraCallbackWithNewForegroundCamera()



    def SetCameraProjection(self, proj):
        SceneRenderJobBase.SetCameraProjection(self, proj)
        self.UpdateBackgroundCameraCallbackWithNewForegroundCamera()



    def GetBackgroundUpdateCallbackFunction(self, foregroundView, foregroundProjection, f):

        def CameraUpdateCallbackClosure():
            return f(foregroundView, foregroundProjection)


        return CameraUpdateCallbackClosure



    def GetBackgroundCameraUpdateFunction(self, backgroundView, backgroundProjection, backgroundNearClip, backgroundFarClip, translation, rotation):
        import geo2
        additionalViewTranform = geo2.MatrixTransformation((0.0, 0.0, 0.0), (0.0, 0.0, 0.0, 1.0), (1.0, 1.0, 1.0), (0.0, 0.0, 0.0), rotation, translation)

        def UpdateBackgroundCamera(foregroundView, foregroundProjection):
            foregroundViewInverted = geo2.MatrixInverse(foregroundView.transform)
            backgroundViewInverted = geo2.MatrixMultiply(foregroundViewInverted, additionalViewTranform)
            backgroundView.transform = geo2.MatrixInverse(backgroundViewInverted)
            originalProjection = foregroundProjection.transform
            if (originalProjection[3][3] == 0):
                new33 = (backgroundFarClip / (backgroundNearClip - backgroundFarClip))
                new43 = ((backgroundNearClip * backgroundFarClip) / (backgroundNearClip - backgroundFarClip))
                newProjectionTransform = (originalProjection[0],
                 originalProjection[1],
                 (originalProjection[2][0],
                  originalProjection[2][1],
                  new33,
                  originalProjection[2][3]),
                 (originalProjection[3][0],
                  originalProjection[3][1],
                  new43,
                  originalProjection[3][3]))
                backgroundProjection.CustomProjection(newProjectionTransform)
            else:
                new33 = (1.0 / (backgroundNearClip - backgroundFarClip))
                new43 = (backgroundNearClip / (backgroundNearClip - backgroundFarClip))
                newProjectionTransform = (originalProjection[0],
                 originalProjection[1],
                 (originalProjection[2][0],
                  originalProjection[2][1],
                  new33,
                  originalProjection[2][3]),
                 (originalProjection[3][0],
                  originalProjection[3][1],
                  new43,
                  originalProjection[3][3]))
                backgroundProjection.CustomProjection(newProjectionTransform)


        return UpdateBackgroundCamera



    def SetBackgroundCameraViewAndProjection(self, view, projection, updateFunction):
        self.backgroundUpdateFunction = None
        if ((view is None) or (projection is None)):
            self.RemoveStep('SET_BACKGROUND_PROJECTION')
            self.RemoveStep('SET_BACKGROUND_VIEW')
            self.RemoveStep('UPDATE_BACKGROUND_CAMERA')
        else:
            self.AddStep('SET_BACKGROUND_VIEW', trinity.TriStepSetView(view))
            self.AddStep('SET_BACKGROUND_PROJECTION', trinity.TriStepSetProjection(projection))
            self.backgroundUpdateFunction = updateFunction
            self.UpdateBackgroundCameraCallbackWithNewForegroundCamera()



    def UpdateBackgroundCameraCallbackWithNewForegroundCamera(self):
        originalView = None
        if (self.view is not None):
            originalView = self.view.object
            if (originalView is None):
                return 
        else:
            return 
        originalProjection = None
        if (self.projection is not None):
            originalProjection = self.projection.object
            if (originalProjection is None):
                return 
        else:
            return 
        if (self.backgroundUpdateFunction is None):
            return 
        if ((originalProjection is not None) and (originalView is not None)):
            callback = self.GetBackgroundUpdateCallbackFunction(originalView, originalProjection, self.backgroundUpdateFunction)
            upd = self.AddStep('UPDATE_BACKGROUND_CAMERA', trinity.TriStepPythonCB())
            if (upd is not None):
                upd.SetCallback(callback)
                return True



    def SetBackgroundScene(self, scene):
        if (scene is None):
            self.RemoveStep('UPDATE_BACKGROUND_SCENE')
            self.RemoveStep('RENDER_BACKGROUND_SCENE')
            self.AddStep('CLEAR_GATHER_RT', trinity.TriStepClear((0, 0, 0, 0), None, None))
            self.RemoveStep('CLEAR_BACKGROUND_RT')
            self.RemoveStep('CLEAR_BACKGROUND_DEPTH')
            self.backgroundScene = None
        else:
            self.AddStep('UPDATE_BACKGROUND_SCENE', trinity.TriStepUpdate(scene))
            self.AddStep('RENDER_BACKGROUND_SCENE', trinity.TriStepRenderScene(scene))
            self.AddStep('CLEAR_BACKGROUND_RT', trinity.TriStepClear((0, 0, 0, 0), 1.0, 0))
            self.AddStep('CLEAR_BACKGROUND_DEPTH', trinity.TriStepClear(None, 1.0, 0))
            self.RemoveStep('CLEAR_GATHER_RT')
            self.backgroundScene = blue.BluePythonWeakRef(scene)



    def EnableSceneUpdate(self, isEnabled):
        if isEnabled:
            self.AddStep('UPDATE_SCENE', trinity.TriStepUpdate(self.GetScene()))
        else:
            self.RemoveStep('UPDATE_SCENE')



    def EnableVisibilityQuery(self, isEnabled):
        if isEnabled:
            result = trinity.Tr2VisibilityResults()
            self.AddStep('VISIBILITY_QUERY', trinity.TriStepVisibilityQuery(self.GetScene(), result))
            self.AddStep('SET_VISIBILITY_RESULT', trinity.TriStepSetVisibilityResults(self.GetScene(), result))
        else:
            self.RemoveStep('VISIBILITY_QUERY ')
            self.RemoveStep('SET_VISIBILITY_RESULT')



    def EnableBackBufferClears(self, isEnabled):
        if isEnabled:
            self.AddStep('CLEAR_PREPASS', trinity.TriStepClear((0, 0, 0, 0), 1.0, 0))
            self.AddStep('CLEAR_LIGHTS', trinity.TriStepClear((0, 0, 0, 0), None, None))
        else:
            self.RemoveStep('CLEAR_PREPASS')
            self.RemoveStep('CLEAR_LIGHTS')



    def SetSSAO(self, ssaoStep):
        if (ssaoStep is not None):
            if (type(self.prePassDepthStencil) is trinity.TriTextureRes):
                ssaoStep.depthTexture = self.prePassDepthStencil
            else:
                ssaoStep.depthTexture = self.prePassRenderTarget
            ssaoStep.normalTexture = self.prePassRenderTarget
            self.AddStep('RENDER_SSAO', ssaoStep)
        else:
            self.RemoveStep('RENDER_SSAO')



    def SetReflections(self, ref0, ref1):
        self.AddStep('SET_VAR_ILR_REFLECTIONS_0', trinity.TriStepSetVariableStore('BloomReflections0', ref0))
        self.AddStep('SET_VAR_ILR_REFLECTIONS_1', trinity.TriStepSetVariableStore('BloomReflections1', ref1))



    def SetBlurKernel(self):
        self.AddBloomStep(self.ilrBloomTarget0, self.ilrBloomTarget1, 0, 1.5)
        self.AddBloomStep(self.ilrBloomTarget1, self.ilrBloomTarget2, 1, 2.5)



    def BrightenILR(self, ilrValue):
        self.SetReflections((-0.6, -0.5, -0.15, -0.3), (1.4,
         1.8,
         -1.5,
         ilrValue))



    def SetLUTMap(self, LUTMap):
        if (LUTMap is None):
            self.postProcessShader['LUTMap'] = None
        elif ('LUTMap' not in self.postProcessShader.parameters):
            param = trinity.TriTexture2DParameter()
            param.name = 'LUTMap'
            self.postProcessShader.parameters['LUTMap'] = param
        self.postProcessShader.parameters['LUTMap'].SetResource(LUTMap)



    def SetLUTInfluence(self, LUTInfluence):
        self.LUTInfluence = LUTInfluence
        if ('LUTInfluence' not in self.postProcessShader.parameters):
            param = trinity.Tr2FloatParameter()
            param.name = 'LUTInfluence'
            self.postProcessShader.parameters['LUTInfluence'] = param
        self.postProcessShader.parameters['LUTInfluence'].value = LUTInfluence



    def EnableLUT(self, enable):
        self.lutEnabled = enable
        self._RebuildPostProcess()



    def HasPostProcess(self):
        return (self.lutEnabled or self.ilrEnabled)



    def EnableILR(self, isEnabled):
        self.ilrEnabled = isEnabled
        self._RebuildPostProcess()



    def _RebuildPostProcess(self):
        BLOOM_BUFFER_SCALE_0 = 4
        BLOOM_BUFFER_SCALE_1 = 4
        BLOOM_BUFFER_SCALE_2 = 8
        device = trinity.device
        width = device.GetPresentParameters()['BackBufferWidth']
        height = device.GetPresentParameters()['BackBufferHeight']
        if self.HasPostProcess():
            if (self.gatherTarget is None):
                self.gatherTarget = device.CreateTexture(width, height, 1, trinity.TRIUSAGE_RENDERTARGET, self.gatherFormat, trinity.TRIPOOL_DEFAULT)
            trinity.GetVariableStore().RegisterVariable('GatherMap', self.gatherTarget)
            if self.ilrEnabled:
                if ((self.ilrBloomFormat is not None) and (self.ilrBloomTarget0 is None)):
                    self.ilrBloomTarget0 = device.CreateTexture((width / BLOOM_BUFFER_SCALE_0), (height / BLOOM_BUFFER_SCALE_0), 1, trinity.TRIUSAGE_RENDERTARGET, self.ilrBloomFormat, trinity.TRIPOOL_DEFAULT)
                    self.ilrBloomTarget1 = device.CreateTexture((width / BLOOM_BUFFER_SCALE_1), (height / BLOOM_BUFFER_SCALE_1), 1, trinity.TRIUSAGE_RENDERTARGET, self.ilrBloomFormat, trinity.TRIPOOL_DEFAULT)
                    self.ilrBloomTarget2 = device.CreateTexture((width / BLOOM_BUFFER_SCALE_2), (height / BLOOM_BUFFER_SCALE_2), 1, trinity.TRIUSAGE_RENDERTARGET, self.ilrBloomFormat, trinity.TRIPOOL_DEFAULT)
                    self.ilrMergeTarget = device.CreateTexture((width / BLOOM_BUFFER_SCALE_0), (height / BLOOM_BUFFER_SCALE_0), 1, trinity.TRIUSAGE_RENDERTARGET, self.ilrBloomFormat, trinity.TRIPOOL_DEFAULT)
            self.InitializeShaders()
            self.AddStep('POST_PROCESS', trinity.TriStepRenderFullScreenShader(self.postProcessShader))
            if self.ilrEnabled:
                self.AddStep('RENDER_ILR_THRESHOLD', trinity.TriStepRenderFullScreenShader(self.ilrThresholdShader))
                self.SetReflections((-0.6, -0.5, -0.15, -0.3), (1.4, 1.8, -1.5, 1))
                self.AddStep('SET_VAR_ILR_MERGE_BLOOM0', trinity.TriStepSetVariableStore('BloomMap', self.ilrBloomTarget0))
                self.AddStep('SET_VAR_ILR_MERGE_BLOOM1', trinity.TriStepSetVariableStore('BloomMap1', self.ilrBloomTarget1))
                self.AddStep('SET_VAR_ILR_MERGE_BLOOM2', trinity.TriStepSetVariableStore('BloomMap2', self.ilrBloomTarget2))
                self.AddStep('SET_ILR_MERGE_RT', trinity.TriStepSetRenderTarget(self.ilrMergeTarget.GetSurfaceLevel(0)))
                self.AddStep('RENDER_ILR_MERGE', trinity.TriStepRenderFullScreenShader(self.ilrMergeShader))
                self.SetBlurKernel()
                trinity.GetVariableStore().RegisterVariable('BloomMap', self.ilrBloomTarget0)
                trinity.GetVariableStore().RegisterVariable('BloomMap1', self.ilrBloomTarget0)
                trinity.GetVariableStore().RegisterVariable('BloomMap2', self.ilrBloomTarget0)
                trinity.GetVariableStore().RegisterVariable('BloomWidth', (0.0, 0.0))
                trinity.GetVariableStore().RegisterVariable('BloomReflections0', (0.0, 0.0, 0.0, 0.0))
                trinity.GetVariableStore().RegisterVariable('BloomReflections1', (0.0, 0.0, 0.0, 0.0))
                self.ilrBloomShader.BindLowLevelShader(['none'])
                self.ilrThresholdShader.BindLowLevelShader(['none'])
                self.ilrMergeShader.BindLowLevelShader(['none'])
            situation = []
            if self.ilrEnabled:
                situation.append('ILR')
            if self.lutEnabled:
                situation.append('LUT')
            self.postProcessShader.BindLowLevelShader(situation)
            self.SetStepAttr('SET_GATHER_RT', 'target', self.gatherTarget.GetSurfaceLevel(0))
            self.AddStep('SET_VAR_POST_PROCESS_GATHER', trinity.TriStepSetVariableStore('GatherMap', self.gatherTarget))
            self.AddStep('SET_POST_PROCESS_COMPOSITE_RT', trinity.TriStepSetRenderTarget(self.backBufferRenderTarget))
            if (self.backgroundScene is not None):
                self.AddStep('SET_BACKGROUND_RT', trinity.TriStepSetRenderTarget(self.gatherTarget.GetSurfaceLevel(0)))
            if self.ilrEnabled:
                self.AddStep('SET_ILR_THRESHOLD_RT', trinity.TriStepSetRenderTarget(self.ilrBloomTarget0.GetSurfaceLevel(0)))
                self.AddStep('SET_VAR_ILR_KERNEL_THRESHOLD', trinity.TriStepSetVariableStore('BloomWidth', ((1.5 / self.gatherTarget.width), (1.5 / self.gatherTarget.height))))
                self.AddStep('SET_VAR_ILR_BLOOM', trinity.TriStepSetVariableStore('BloomMap', self.ilrMergeTarget))
        else:
            self.RemoveStep('RENDER_ILR_THRESHOLD')
            self.RemoveStep('POST_PROCESS')
            self.RemoveStep('SET_VAR_ILR_MERGE_BLOOM0')
            self.RemoveStep('SET_VAR_ILR_MERGE_BLOOM1')
            self.RemoveStep('SET_VAR_ILR_MERGE_BLOOM2')
            self.RemoveStep('SET_ILR_MERGE_RT')
            self.RemoveStep('RENDER_ILR_MERGE')
            self.RemoveStep('SET_ILR_THRESHOLD_RT')
            self.RemoveStep('SET_VAR_ILR_KERNEL_THRESHOLD')
            self.RemoveStep('SET_VAR_POST_PROCESS_GATHER')
            self.RemoveStep('SET_POST_PROCESS_COMPOSITE_RT')
            self.RemoveStep('SET_VAR_ILR_BLOOM')
            self.RemoveStep('SET_VAR_ILR_REFLECTIONS_0')
            self.RemoveStep('SET_VAR_ILR_REFLECTIONS_1')
            self.RemoveStep('SET_VAR_ILR_THRESHOLD_0')
            self.RemoveStep('SET_VAR_ILR_KERNEL_0')
            self.RemoveStep('SET_ILR_BLOOM_RT_0')
            self.RemoveStep('RENDER_ILR_BLOOM_0')
            self.RemoveStep('SET_VAR_ILR_THRESHOLD_1')
            self.RemoveStep('SET_VAR_ILR_KERNEL_1')
            self.RemoveStep('SET_ILR_BLOOM_RT_1')
            self.RemoveStep('RENDER_ILR_BLOOM_1')
            self.AddStep('SET_GATHER_RT', trinity.TriStepSetRenderTarget(self.backBufferRenderTarget))
            if (self.backgroundScene is not None):
                self.AddStep('SET_BACKGROUND_RT', trinity.TriStepSetRenderTarget(self.backBufferRenderTarget))



    def SetRenderTargets(self, backBufferDepthStencil, backBufferRenderTarget, prePassDepthStencil, prePassRenderTarget, lightAccumulationTarget, ilrBloomTarget0, ilrBloomTarget1, ilrBloomTarget2, ilrMergeTarget, gatherTarget):
        if (prePassRenderTarget is not None):
            self.SetStepAttr('SET_PREPASS_RT', 'target', prePassRenderTarget.GetSurfaceLevel(0))
        else:
            self.SetStepAttr('SET_PREPASS_RT', 'target', None)
        if (lightAccumulationTarget is not None):
            self.SetStepAttr('SET_LIGHT_RT', 'target', lightAccumulationTarget.GetSurfaceLevel(0))
        else:
            self.SetStepAttr('SET_LIGHT_RT', 'target', None)
        if (prePassDepthStencil is not None):
            if (type(prePassDepthStencil) is trinity.TriTextureRes):
                self.AddStep('SET_DEPTH', trinity.TriStepSetDepthStencil(prePassDepthStencil.GetSurfaceLevel(0)))
                self.AddStep('SET_VAR_LIGHTS_DEPTH', trinity.TriStepSetVariableStore('LightPrePassDepthMap', prePassDepthStencil))
            else:
                if (type(prePassDepthStencil) is trinity.TriSurface):
                    self.SetStepAttr('SET_DEPTH', 'target', prePassDepthStencil)
        else:
            self.SetStepAttr('SET_DEPTH', 'target', None)
        self.SetStepAttr('RESTORE_DEPTH', 'target', backBufferDepthStencil)
        self.AddStep('SET_VAR_LIGHTS_PREPASS', trinity.TriStepSetVariableStore('LightPrePassMap', prePassRenderTarget))
        self.AddStep('SET_VAR_LIGHTS', trinity.TriStepSetVariableStore('LightAccumulationMap', lightAccumulationTarget))
        if (type(prePassDepthStencil) is trinity.TriTextureRes):
            self.SetStepAttr('RENDER_SSAO', 'depthTexture', prePassDepthStencil)
        else:
            self.SetStepAttr('RENDER_SSAO', 'depthTexture', prePassRenderTarget)
        self.SetStepAttr('RENDER_SSAO', 'normalTexture', prePassRenderTarget)
        if (gatherTarget is not None):
            self.SetStepAttr('SET_GATHER_RT', 'target', gatherTarget.GetSurfaceLevel(0))
            if (self.backgroundScene is not None):
                self.AddStep('SET_BACKGROUND_RT', trinity.TriStepSetRenderTarget(gatherTarget.GetSurfaceLevel(0)))
            self.AddStep('SET_VAR_POST_PROCESS_GATHER', trinity.TriStepSetVariableStore('GatherMap', gatherTarget))
            self.AddStep('SET_POST_PROCESS_COMPOSITE_RT', trinity.TriStepSetRenderTarget(backBufferRenderTarget))
        else:
            self.SetStepAttr('SET_GATHER_RT', 'target', backBufferRenderTarget)
            if (self.backgroundScene is not None):
                self.AddStep('SET_BACKGROUND_RT', trinity.TriStepSetRenderTarget(backBufferRenderTarget))
            self.RemoveStep('SET_POST_PROCESS_COMPOSITE_RT')
        if (ilrBloomTarget0 is not None):
            self.AddStep('SET_ILR_THRESHOLD_RT', trinity.TriStepSetRenderTarget(ilrBloomTarget0.GetSurfaceLevel(0)))
            self.AddStep('SET_VAR_ILR_KERNEL_THRESHOLD', trinity.TriStepSetVariableStore('BloomWidth', ((1.5 / gatherTarget.width), (1.5 / gatherTarget.height))))
            self.AddStep('SET_VAR_ILR_BLOOM', trinity.TriStepSetVariableStore('BloomMap', ilrMergeTarget))
        else:
            self.RemoveStep('SET_ILR_THRESHOLD_RT')
            self.RemoveStep('SET_VAR_POST_PROCESS_GATHER')
            self.RemoveStep('SET_VAR_ILR_BLOOM')



    def GetRenderTargets(self):
        return self.renderTargetList



    def SetClearColor(self, color):
        step = self.GetStep('CLEAR_BACKGROUND_RT')
        if (step is not None):
            step.color = color




